//
// Created by kero-ly on 2020/6/12.
//

#ifndef CLION_LY_SORT_H
#define CLION_LY_SORT_H

#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <functional>

#include "../utils/utils.h"
using std::string;
using std::vector;

using sortCall = std::function<vector<int>(vector<int>&)>;
using sortFun = std::pair<string, sortCall>;

class LySort {
public:
    LySort() = default;
    ~LySort() = default;
    LySort(LySort&) = delete;
    LySort& operator=(LySort&) = delete;
    LySort(LySort&&) = delete;
    LySort& operator=(LySort&&) = delete;

    // 工具
    timer timer_;

    void printVec(vector<int>& v) {
        std::cout << "[ ";
        for (int i:v)
            std::cout << i << " ";
        std::cout << "]" << std::endl;
    }

    // 主入口
    void sortMain() {
        std::cout << "Before sort: " << std::endl;
        for (auto v:examples)
            printVec(v);

        // 按模板添加新的函数，后面统一调用
        func_vector.emplace_back(std::make_pair("selectSort",[&](vector<int>& v) -> vector<int> {return selectSort(v);}));
        func_vector.emplace_back(std::make_pair("bubbleSort",[&](vector<int>& v) -> vector<int> {return bubbleSort(v);}));
        func_vector.emplace_back(std::make_pair("insertSort",[&](vector<int>& v) -> vector<int> {return insertSort(v);}));
        func_vector.emplace_back(std::make_pair("insertSort_with_binarySearch",[&](vector<int>& v) -> vector<int> {return insertSort_with_binarySearch(v);}));

        for (auto& fun : func_vector) {
            std::cout << "After " << fun.first << ": " << std::endl;
            for (auto& v : examples) {
                timer_.tic();
                vector<int> ret = fun.second(v);
                timer_.toc();
                printVec(ret);
            }
        }
    }

    // 各种排序函数
    vector<int> selectSort(vector<int>& v);
    vector<int> bubbleSort(vector<int>& v);
    vector<int> insertSort(vector<int>& v);
    vector<int> insertSort_with_binarySearch(vector<int> &v);

private:
    // 存放所有排序算法函数
    vector<sortFun> func_vector;
    // 排序算法测试输入
    vector<vector<int> > examples = {{1,5,7,3,2,0,8,4,9,6},   // 完全无序
                                     {9,8,7,6,5,4,3,2,1,0},   // 倒序
                                     {0,1,2,9,4,5,6,7,3,8},   // 大部分有序
                                     {0,1,2,3,3,5,3,7,9,8},   // 重复元素(如何证明稳定性？
                                     {0},                     // 单元素
                                     {}};                     // 空元素
};



#endif //CLION_LY_SORT_H
